<?php

require_once 'db.php';

/**
 * General action that does something with the profile or preferences.
 * This class must be subclassed.
 */
abstract class _UserSettingsAction extends Action {
	
	// Mapping to User data entity
	const INPUT_PASSWORD = User::password;
	const INPUT_FIRST_NAME = User::first_name;
	const INPUT_LAST_NAME = User::last_name;
	const INPUT_DATE_OF_BIRTH = User::date_of_birth;
	const INPUT_GENDER = User::gender;
	const INPUT_FACEBOOK = User::facebook;
	const INPUT_KNOWN_LANGUAGES = User::known_languages;
	const INPUT_ABOUT_YOURSELF = User::about_yourself;
	const INPUT_NEWSLETTER = User::newsletter;
	const INPUT_EMAIL_WHEN_NEW_MATCH = User::email_when_new_match;
	const INPUT_INVISIBLE = User::invisible;
	
	const INPUT_UNKNOWN_LANGUAGES_AND_LEVELS = User::unknown_languages_and_levels;
	//const INPUT_PARTNER_MIN_AGE = ;
	//const INPUT_PARTNER_MAX_AGE = ;
	//const INPUT_PARTNER_GENDER = ;
	
	public function add_profile_inputs() {
		$this->add_input(new TextInput(_UserSettingsAction::INPUT_FIRST_NAME, 'First name', $min_length=2));
		$this->add_input(new TextInput(_UserSettingsAction::INPUT_LAST_NAME, 'Last name', $min_length=2));
		$this->add_input(new DateInput(_UserSettingsAction::INPUT_DATE_OF_BIRTH, 'Date of birth'));
		$this->add_input(new GenderInput(_UserSettingsAction::INPUT_GENDER, 'Gender'));
		
		$this->add_input(new Input(_UserSettingsAction::INPUT_FACEBOOK, 'Facebook url (optional)', new FacebookCheck()));
		
		$this->add_input(new TextInput(
			_UserSettingsAction::INPUT_ABOUT_YOURSELF, 
			'About yourself (optional, short)',
			$min_length=0, $max_length=500
		));
		
		$this->add_input(new ListInput(
			_UserSettingsAction::INPUT_KNOWN_LANGUAGES, 
			'Languages you speak fluently and others can learn from you', 
			new LanguageCodeInput(null),
			1
		));
		
		$this->add_input(new BooleanInput(
			_UserSettingsAction::INPUT_EMAIL_WHEN_NEW_MATCH, 
			'Send me an email when new matching profiles appear in my match results'
		));
		
		$this->add_input(new BooleanInput(
			_UserSettingsAction::INPUT_INVISIBLE, 
			'Make me invisible (blocks messaging too)'
		));
		
		$this->add_input(new BooleanInput(
			_UserSettingsAction::INPUT_NEWSLETTER, 
			'Send me an email when events are announced'
		));
		
	}
	
	public function add_criteria_inputs() {
		$this->add_input(new ListInput(
			_UserSettingsAction::INPUT_UNKNOWN_LANGUAGES_AND_LEVELS, 
			'Languages you want to learn and your current level', 
			new TupleInput(null, null, array(
				new LanguageCodeInput(null, 'Language'), 
				new LevelInput(null, 'Your current level')
			)),
			1
		));
		
		// Is this really necessary?
		/*$this->add_input(new IntegerInput(
			_UserSettingsAction::INPUT_PARTNER_MIN_AGE,
			'Minimum age of partner',
			$min=16, $max=40));
		$this->add_input(new IntegerInput(
			_UserSettingsAction::INPUT_PARTNER_MAX_AGE,
			'Maximum age of partner',
			$min=16, $max=40));*/

		// Is this really necessary?
		/*
		$gender_obj = new GenderInput(null, null);
		$choices = array_merge((array) "Doesn't matter", $gender_obj->get_choices());
		$choice = $this->add_input(new MultiChoiceInput(
			_UserSettingsAction::INPUT_PARTNER_GENDER,
			'Preferred gender of tandem partner', 
			$choices
		));
		*/
		
	}
	
	public function add_password_input() {
		$this->add_input(new TextInput(_UserSettingsAction::INPUT_PASSWORD, 'Password', $min_length=0, $max_length=50));
	}
	
	
	/**
	 * Safely extract data from the request. The data is escaped
	 * @param array $request
	 * @returns $data user data
	 */
	protected function extract_profile_inputs($request) {
		// HTML-escape user provided stuff (users writing HTML are up to no good)
		// Known languages is JSON, and only consists of allowed states
		$request = htmlentities_array($request, $skip=array(
			_UserSettingsAction::INPUT_KNOWN_LANGUAGES,
		));
		
		// Because of the way the inputs are defined (equal), the keys in the request
		// are the keys for user data
		$data = array_extract($request, array(
			_UserSettingsAction::INPUT_FIRST_NAME,
			_UserSettingsAction::INPUT_LAST_NAME,
			_UserSettingsAction::INPUT_GENDER,
			_UserSettingsAction::INPUT_ABOUT_YOURSELF,
			_UserSettingsAction::INPUT_FACEBOOK,
			_UserSettingsAction::INPUT_NEWSLETTER,
			_UserSettingsAction::INPUT_EMAIL_WHEN_NEW_MATCH,
			_UserSettingsAction::INPUT_INVISIBLE,
		));
		
		// These need additional processing
		$data[_UserSettingsAction::INPUT_DATE_OF_BIRTH]	= 
			slash_date_string_to_date($request[_UserSettingsAction::INPUT_DATE_OF_BIRTH]);
		$data[_UserSettingsAction::INPUT_KNOWN_LANGUAGES] = 
			json_decode($request[_UserSettingsAction::INPUT_KNOWN_LANGUAGES]);
			
		return $data;
	}
	
	protected function extract_criteria_inputs($request) {
		return array(
				_UserSettingsAction::INPUT_UNKNOWN_LANGUAGES_AND_LEVELS =>
				json_decode($request[_UserSettingsAction::INPUT_UNKNOWN_LANGUAGES_AND_LEVELS])
		);
	}
	
	protected function extract_password_inputs($request) {
		return array(
				_UserSettingsAction::INPUT_PASSWORD =>
				$request[_UserSettingsAction::INPUT_PASSWORD]
		);
	}
	
	protected function update_user($data) {
		$user = $_SESSION['user'];
		$user->update($data);
		global $DB;
		$DB->save_user($user);
		return $user;
	}
	
}


class FacebookCheck extends Check {
	
	private $facebook_url_start = 'http://www.facebook.com/';
	
	public function comment($alias) {
		return 'You have to provide the entire facebook url, like http://www.facebook.com/you';
	}
	
	public function validate_php($value) {
		return strlen($value) == 0 || starts_with($value, $this->facebook_url_start);
	}
	
	public function validate_js($value) { return "
		return $value.length == 0 || $value.substr(0, ".strlen($this->facebook_url_start).") === '{$this->facebook_url_start}';
	";}
}


class LevelInput extends MultiChoiceInput {
	
	public static $levels = array( 
		10 => 'Basic', 
		50 => 'Intermediate', 
		80 => 'Advanced',
	);
	
	public function __construct($name=null, $alias=null) {
		parent::__construct($name, $alias, LevelInput::$levels);
	}
	
}

?>